package com.demo.date.entity;


import com.demo.date.utils.DateTimeUtils;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.http.util.Asserts;

import java.time.Duration;
import java.time.Instant;
import java.util.Date;
import java.util.Objects;

/**
 * @Author: tomato
 * @Date: 2021/1/15 13:27
 */
@NoArgsConstructor
@Data
@Builder
@AllArgsConstructor
public class DateDto {

    private Date startTime;

    private Date endTime;

    public DateDto(Date startTime, Date endTime) {
        this.startTime = startTime;
        this.endTime = endTime;
    }

    private volatile Date startPoint;

    private static final int DAYS_DURATION = 30;

    private volatile long totalDays;

    public synchronized Pair<Date, Date> next() {
        initStartPoint();
        totalDays -= DAYS_DURATION;
        Date start = startPoint;
        Date end = DateTimeUtils.plusDate(startPoint, DAYS_DURATION);
        Asserts.notNull(end, "endTime is not null");
        if (end.compareTo(endTime) > 0) {
            end = DateTimeUtils.plusDate(endTime, 1);
        }
        startPoint = end;
        return Pair.of(start, end);
    }

    private void initStartPoint() {
        if (Objects.isNull(startPoint)) {
            startPoint = startTime;
            Instant start = Instant.ofEpochMilli(this.startPoint.getTime());
//            Instant end = Instant.ofEpochMilli(null != endTime ? endTime.getTime() : new Date().getTime());
            Instant end = Instant.ofEpochMilli(null != endTime ? endTime.getTime() :System.currentTimeMillis());
            Duration between = Duration.between(start, end);
            totalDays = between.toDays() + 1;
        }
    }

    public synchronized boolean hasNext() {
        if (!validation()) {
            return false;
        }
        initStartPoint();
        return (this.startPoint.compareTo(endTime) < 0 || this.startPoint.compareTo(new Date()) < 0) && totalDays > 0;
    }

    public boolean validation() {
        if (Objects.isNull(this.getStartTime()) || Objects.isNull(this.getEndTime())) {
            return false;
        }
        return true;
    }
}
